package com.qf.sy2103.ssm.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.sy2103.ssm.constants.Constants;
import com.qf.sy2103.ssm.dao.UserDao;
import com.qf.sy2103.ssm.entity.User;
import com.qf.sy2103.ssm.service.UserServcie;
import com.qf.sy2103.ssm.vo.PageVo;
import com.qf.sy2103.ssm.vo.TableVo;
import com.qf.sy2103.ssm.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class UserServiceImpl implements UserServcie {

    @Autowired
    private UserDao userDao;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public User getUser(Integer id) {

        //1. 参数校验
        System.out.println("UserServiceImpl 方法：getUser 接收到的参数id为："+id);

        //2. 调用dao层的对象查询数据库
        System.out.println("UserServiceImpl 调用dao层的核心方法：userDao.getUserById 参数id为："+id);
        final User user = userDao.getUserById(id);

        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertUser(User user) throws SQLException {
        userDao.insertUser(user);
        int a = 1/0;
      /*  if (1==1){
            throw new SQLException();
        }*/
        userDao.insertUser(user);
        return 2;

    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Boolean checkUserLogin(UserVo userVo) {

        log.debug("入参为:{}",userVo);

        // 根据用户名去数据库查询，看看该用户名的用户是否存在
        User user = userDao.getUserByName(userVo.getName());
        if(user==null){
            return false;  // 用户不存，直接返回失败
        }
        // 比较数据库中的密码和当前请求参数中的密码是否一致
        final String dbpassword = user.getPassword();
        if(dbpassword.equals(userVo.getPassword())){
            // 把数据库中查询到的user对象复制给userVo
            userVo.setDbuser(user);
            return true;
        }else{
            return false;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean registUser(UserVo userVo, MultipartFile source, String realPath) {
        log.debug("入参：{},{},{}",userVo,source,realPath);

        try {
            // 1. 处理文件上传，把文件存放到指定目录
            //文件的原始名称
            String filename = source.getOriginalFilename();
            //定制全局唯一的命名
            String unique = UUID.randomUUID().toString();
            //获得文件的后缀
            String ext = FilenameUtils.getExtension(filename);//abc.txt   txt    hello.html  html
            //定制全局唯一的文件名
            String uniqueFileName = unique+"."+ext;
            log.debug("头像的文件名为:{}",uniqueFileName);
            File file = new File(realPath);
            if (!file.exists()) {
                file.mkdirs();
            }

            source.transferTo(new File(realPath+"\\"+uniqueFileName));
            log.debug("头像的存储路径为:{}",realPath+"\\"+uniqueFileName);
            // 2. 检查当前的用户名是否已经存在了
            List<User> users = userDao.getUsersByName(userVo.getName());
            if (users.size()>0){
                return false;  // 重名注册失败
            }
            log.debug("当前用户名没有注册过:{}",userVo.getName());
            // 3. 把用户数据写入数据库表，注意要把生成的文件名也写入

            final User user = new User();

            BeanUtils.copyProperties(userVo,user);  // 从 userVo 拷贝属性 到user对象
            user.setFilename(uniqueFileName);
            user.setRegistTime(new Date());

            log.debug("写入数据的注册的用户的 信息为：{}",user);
            userDao.insertUser(user);

            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }


    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public TableVo<User> getAllUsers(PageVo pageVo) {
        // 指定下一条sql语句的分页信息
        PageHelper.startPage(pageVo.getPage(),pageVo.getLimit());
        List<User> users  =  userDao.getAllUsers();
        final PageInfo<User> userPageInfo = new PageInfo<>(users);

//        final TableVo<User> userTableVo = new TableVo<>();
//        userTableVo.setCode(0);
//        userTableVo.setMsg("ok");
//        userTableVo.setCount(userPageInfo.getTotal());
//        userTableVo.setData(users);

//        TableVo.ok(0,"ok",userPageInfo.getTotal(),users);

        return new TableVo<User>(0,"ok",userPageInfo.getTotal(),users);
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public TableVo<User> getAllUsers(PageVo pageVo, User user) {

        PageHelper.startPage(pageVo.getPage(),pageVo.getLimit());
        List<User> users  =  userDao.getAllUsersByCondition(user);
        final PageInfo<User> userPageInfo = new PageInfo<>(users);
        return new TableVo<User>(0,"ok",userPageInfo.getTotal(),users);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public String exportAllData(String realPath) throws IOException {

        // 1. 调用 userDao 查出所有的用户数据
        final List<User> allUsers = userDao.getAllUsers();

        // 2. 把数据写入文件
        File file = new File(realPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        //定制全局唯一的命名
        String unique = UUID.randomUUID().toString()+ Constants.FILE_DOWNLOAD_EXT;

        final String finalFileName = realPath + File.separator + unique ;

        log.debug("导出的文件为：{}",finalFileName);
        writeListToFile(finalFileName, allUsers);

        return unique;
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public String exportAllDataBatch(String realPath) throws IOException {

        // 2. 把数据写入文件
        File file = new File(realPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        //定制全局唯一的命名
        String unique = UUID.randomUUID().toString()+ Constants.FILE_DOWNLOAD_EXT;

        final String finalFileName = realPath + File.separator + unique ;

        log.debug("导出的文件为：{}",finalFileName);

        // 1. 分批导出，到底分多少批呢？
        Integer pageSize = Constants.FILE_EXPORT_BATCH_PAGESIZE;

        Integer count = userDao.getTotalCount();

        Integer times = 0; // 需要循环多少次

        if( count%pageSize == 0 ){  // 整除时
            times = count / pageSize;
        }else{
            times = count / pageSize + 1;
        }
        log.debug("导出的数据量为：{}，页大小为：{}，批次数量为：{}",count,pageSize,times);
        for (int i = 0; i < times; i++) {

            PageHelper.startPage((i+1),pageSize);
            final List<User> allUsers = userDao.getAllUsers();

            writeListToFile(finalFileName, allUsers);
        }


        return unique;
    }

    private void writeListToFile(String finalFileName, List<User> allUsers) throws IOException {
        final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File(finalFileName), true));

        for (User user : allUsers) {
            String s = user.toCSVString(); // 把user对象转换成逗号分割的字符串
            bufferedWriter.write(s);
            bufferedWriter.newLine();
        }

        bufferedWriter.flush();
        bufferedWriter.close();
    }


}
